package user

import (
	"encoding/json"
	"fmt"
	"github.com/DanPlayer/randomname"
	"github.com/gin-gonic/gin"
	"github.com/xlstudio/wxbizdatacrypt"
	"net/http"
	"shangyuapi/data_source"
	"shangyuapi/models"
	"shangyuapi/service"
	"time"
)

const (
	code2sessionURL = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
	appID           = "wx32230ce280fc5bc2"
	appSecret       = "667782e3cf101f6554212ddb9d13e779"
)

type KDRespBody struct {
	Code string `json:"code" from:"code"`
}

func Jiamijiemi(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	code := json1.Code
	var miyao string
	miyao = service.Miyao()
	key := []byte(miyao)
	phonejm1, _ := service.Encrypt(key, code)
	phonejm2, _ := service.Decrypt(key, phonejm1)

	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    phonejm1,
		"data1":   phonejm2,
		"msg":     "ok",
	})
	return

}

func Loginxcx(ctx *gin.Context) {
	json1 := KDRespBody{}
	ctx.ShouldBind(&json1)
	wxMap, err := sendWxAuthAPI(json1.Code)

	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "服务出错",
		})
		return
	}
	if _, ok := wxMap["errcode"]; ok {
		fmt.Println(wxMap["errmsg"])
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "请重新登录",
		})
		return
	}
	routine_openid := wxMap["openid"].(string)
	//unionid := wxMap["unionid"].(string)
	unionid := ""
	session_key := wxMap["session_key"].(string)
	reqip := ctx.ClientIP()
	var uid int64
	var user models.User
	data_source.Db.Where("routine_openid = ?", routine_openid).First(&user)
	if user.ID > 0 {
		upuser1 := models.User{
			LoginIp:    reqip,
			LoginTime:  time.Now().Unix(),
			LoginNum:   user.LoginNum + 1,
			SessionKey: session_key,
		}
		data_source.Db.Where("routine_openid = ?", routine_openid).Updates(upuser1)
		uid = user.ID
	} else {
		adduser := models.User{
			LoginTime:     time.Now().Unix(),
			LoginIp:       reqip,
			RoutineOpenid: routine_openid,
			CreateTime:    time.Now().Unix(),
			LoginNum:      1,
			Unionid:       unionid,
			Newuser:       1,
			Ziliao:        1,
			Xiangce:       1,
			Jichuziliao:   1,
			Xingxiziliao:  1,
			Jybz:          1,
			Grbq:          1,
			Grms:          1,
			Zlrz:          1,
			Shenhe:        1,
			SessionKey:    session_key,
			Logo:          "shanyu/2024-10-10/1728539100头像2.png.png",
			Nickname:      randomname.GenerateName(),
		}
		data_source.Db.Create(&adduser)
		uid = adduser.ID
	}

	var usernew models.User
	data_source.Db.Where("id = ?", uid).First(&usernew)
	var miyao string
	miyao = service.Miyao()
	key := []byte(miyao)
	phonejm, _ := service.Decrypt(key, usernew.Phone)
	usernew.Phone = phonejm
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    usernew,
		"msg":     "ok",
	})
	return

}

type Requesttoken struct {
	AccessToken string           `json:"access_token,omitempty"`
	User        Requesttokenuser `json:"user,omitempty"`
}
type Requesttokenuser struct {
	Uuid string `json:"uuid,omitempty"`
}

func sendWxAuthAPI(code string) (map[string]interface{}, error) {
	var wxMap map[string]interface{}
	url := fmt.Sprintf(code2sessionURL, appID, appSecret, code)
	fmt.Println(url)
	resp, err := http.DefaultClient.Get(url)

	if err != nil {
		return wxMap, err
	}

	err = json.NewDecoder(resp.Body).Decode(&wxMap)
	if err != nil {
		return wxMap, err
	}
	defer resp.Body.Close()

	return wxMap, nil
}

// 手机号解密
type PhoneJmBody struct {
	EncryptedData string `json:"encryptedData" from:"encryptedData"`
	Iv            string `json:"iv" from:"iv"`
	Uid           int64  `json:"uid" from:"uid"`
}

func PhoneJm(ctx *gin.Context) {
	request := PhoneJmBody{}
	ctx.ShouldBind(&request)
	encryptedData := request.EncryptedData
	iv := request.Iv
	uid := request.Uid
	var user models.User
	data_source.Db.Where("id = ?", uid).First(&user)
	//fmt.Println(appID)
	//fmt.Println(user.SessionKey)
	pc := wxbizdatacrypt.WxBizDataCrypt{AppId: appID, SessionKey: user.SessionKey}

	result, err := pc.Decrypt(encryptedData, iv, false) //第三个参数解释： 需要返回 JSON 数据类型时 使用 true, 需要返回 map 数据类型时 使用 false
	//fmt.Println(result)
	//fmt.Println(err)
	//return
	if err != nil {
		fmt.Println(err)
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 0,
			"data":    err,
			"msg":     "no",
		})
		return
	} else {
		if resultMap, ok := result.(map[string]interface{}); ok {
			phone := resultMap["phoneNumber"]
			var miyao string
			miyao = service.Miyao()
			key := []byte(miyao)
			phonejm, _ := service.Encrypt(key, phone.(string))

			data_source.Db.Model(&models.User{}).Where("id = ?", uid).Update("phone", phonejm)
			var userinfo models.User
			data_source.Db.Where("id = ?", uid).First(&userinfo)
			userinfo.Phone = phone.(string)
			ctx.JSON(http.StatusOK, gin.H{
				"code":    0,
				"error":   0,
				"success": 200,
				"data":    userinfo,
				"msg":     "ok",
			})
			return
		}

	}

}

type PhonebdBody struct {
	Phone     string `json:"phone" gorm:"phone"`
	Phonecode string `json:"phonecode" gorm:"phonecode"`
	Uid       int64  `json:"uid" gorm:"uid"`
}

func Phonebd(ctx *gin.Context) {
	request := PhonebdBody{}
	ctx.ShouldBind(&request)
	phone := request.Phone
	phonecode := request.Phonecode
	uid := request.Uid
	if phonecode == "" {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "请填写验证码",
		})
		return
	}
	var code models.Phonecode
	data_source.Db.Where("phone = ?", phone).Where("enttime >= ?", time.Now().Unix()).Last(&code)
	if code.ID == 0 {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "请从新获取验证码",
		})
		return
	}
	if code.Code != phonecode {
		ctx.JSON(http.StatusOK, gin.H{
			"code":    400,
			"error":   1,
			"success": 400,
			"data":    "on",
			"msg":     "验证码错误",
		})
		return
	}
	var miyao string
	miyao = service.Miyao()
	key := []byte(miyao)
	phonejm, _ := service.Encrypt(key, phone)
	data_source.Db.Model(&models.User{}).Where("id = ?", uid).Update("phone", phonejm)
	var userinfo models.User
	data_source.Db.Where("id = ?", uid).First(&userinfo)
	userinfo.Phone = phone
	ctx.JSON(http.StatusOK, gin.H{
		"code":    0,
		"error":   0,
		"success": 200,
		"data":    userinfo,
		"msg":     "ok",
	})
	return
}
